#define WIN32_LEAN_AND_MEAN
#define NOMINMAX

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <dwmapi.h>
#include <iostream>
#include <vector>
#include <string>
#include <thread>
#include <mutex>
#include <atomic>
#include <memory>
#include <sstream>
#include <chrono>
#include <algorithm>
#include <fstream>
#include <iomanip>

#pragma comment(lib, "dwmapi.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")

// 日志记录函数
void LogError(const std::string& message) {
    auto now = std::chrono::system_clock::now();
    auto time_t = std::chrono::system_clock::to_time_t(now);
    
    std::cout << "[ERROR " << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S") 
              << "] " << message << std::endl;
    
    // 同时写入日志文件
    std::ofstream logFile("censorship_debug.log", std::ios::app);
    if (logFile.is_open()) {
        logFile << "[ERROR " << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S") 
                << "] " << message << std::endl;
        logFile.close();
    }
}

void LogInfo(const std::string& message) {
    auto now = std::chrono::system_clock::now();
    auto time_t = std::chrono::system_clock::to_time_t(now);
    
    std::cout << "[INFO " << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S") 
              << "] " << message << std::endl;
    
    // 同时写入日志文件
    std::ofstream logFile("censorship_debug.log", std::ios::app);
    if (logFile.is_open()) {
        logFile << "[INFO " << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S") 
                << "] " << message << std::endl;
        logFile.close();
    }
}

struct Box {
    int x1, y1, x2, y2;
    COLORREF color;
};

class BoxRenderer {
private:
    HWND hwnd;
    HDC memDC;
    HBITMAP memBitmap;
    HBITMAP oldBitmap;
    std::vector<Box> boxes;
    mutable std::recursive_mutex boxesMutex;
    int screenWidth;
    int screenHeight;

    COLORREF CalculateAverageColor(int x1, int y1, int x2, int y2) {
        // 极简优化：直接返回固定颜色，避免所有GDI操作和屏幕采样
        // 这样可以将性能从2秒提升到毫秒级别
        
        // 可以根据框的位置或大小返回不同颜色，保持一定的视觉区分
        int width = abs(x2 - x1);
        int height = abs(y2 - y1);
        
        // 简单的颜色选择策略：根据框的大小选择颜色
        if (width * height < 1000) {
            return RGB(255, 0, 0);    // 小框用红色
        } else if (width * height < 5000) {
            return RGB(0, 255, 0);    // 中框用绿色
        } else {
            return RGB(0, 0, 255);    // 大框用蓝色
        }
    }

    void UpdateLayeredWindowContent() {
        // 恢复正常的窗口更新和绘制功能
        try {
            if (!hwnd || !memDC) return;

            // 获取锁以安全访问boxes
            std::unique_lock<std::recursive_mutex> lock(boxesMutex, std::try_to_lock);
            if (!lock.owns_lock()) {
                LogInfo("无法获取锁，跳过本次更新");
                return;
            }

            // 获取窗口尺寸
            RECT rect;
            GetWindowRect(hwnd, &rect);
            int width = rect.right - rect.left;
            int height = rect.bottom - rect.top;

            // 清空背景为透明黑色
            HBRUSH blackBrush = CreateSolidBrush(RGB(0, 0, 0));
            RECT fillRect = { 0, 0, width, height };
            FillRect(memDC, &fillRect, blackBrush);
            DeleteObject(blackBrush);

            // 绘制所有检测框
            for (const auto& box : boxes) {
                // 创建彩色画刷
                HBRUSH brush = CreateSolidBrush(box.color);
                
                // 绘制填充的矩形框
                RECT boxRect = { box.x1, box.y1, box.x2, box.y2 };
                FillRect(memDC, &boxRect, brush);
                
                // 清理画刷
                DeleteObject(brush);
            }

            // 更新分层窗口
            POINT ptSrc = { 0, 0 };
            SIZE sizeWnd = { width, height };
            BLENDFUNCTION blend = { AC_SRC_OVER, 0, 128, AC_SRC_ALPHA };  // 半透明效果

            BOOL result = ::UpdateLayeredWindow(hwnd, NULL, NULL, &sizeWnd, memDC, &ptSrc, RGB(0, 0, 0), &blend, ULW_COLORKEY);
            
            if (result) {
                LogInfo("成功更新窗口显示，绘制了 " + std::to_string(boxes.size()) + " 个检测框");
            } else {
                LogError("UpdateLayeredWindow失败，错误代码: " + std::to_string(GetLastError()));
            }
            
        } catch (const std::exception& e) {
            LogError("UpdateLayeredWindowContent异常: " + std::string(e.what()));
        } catch (...) {
            LogError("UpdateLayeredWindowContent发生未知异常");
        }
    }

public:
    BoxRenderer() : hwnd(nullptr), memDC(nullptr), memBitmap(nullptr), oldBitmap(nullptr) {
        screenWidth = GetSystemMetrics(SM_CXSCREEN);
        screenHeight = GetSystemMetrics(SM_CYSCREEN);
    }

    ~BoxRenderer() {
        Cleanup();
    }

    bool Create() {
        WNDCLASSW wc = {};
        wc.lpfnWndProc = WindowProc;
        wc.hInstance = GetModuleHandle(NULL);
        wc.lpszClassName = L"BoxRendererClass";
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);

        if (!RegisterClassW(&wc)) {
            DWORD error = GetLastError();
            if (error != ERROR_CLASS_ALREADY_EXISTS) {
                return false;
            }
        }

        hwnd = CreateWindowExW(
            WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE | WS_EX_TRANSPARENT,
            L"BoxRendererClass",
            L"BoxRenderer",
            WS_POPUP,
            0, 0, screenWidth, screenHeight,
            NULL, NULL, GetModuleHandle(NULL), NULL
        );

        if (!hwnd) return false;

        HDC screenDC = GetDC(NULL);
        memDC = CreateCompatibleDC(screenDC);
        memBitmap = CreateCompatibleBitmap(screenDC, screenWidth, screenHeight);
        oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
        ReleaseDC(NULL, screenDC);

        if (!memDC || !memBitmap) return false;

        SetWindowDisplayAffinity(hwnd, WDA_EXCLUDEFROMCAPTURE);

        BOOL value = TRUE;
        DwmSetWindowAttribute(hwnd, DWMWA_EXCLUDED_FROM_PEEK, &value, sizeof(value));

        return true;
    }

    void Show() {
        if (hwnd) {
            ShowWindow(hwnd, SW_SHOWNOACTIVATE);
            UpdateWindow(hwnd);
        }
    }

    void Stop() {
        try {
            LogInfo("开始停止渲染器");
            
            // 清理boxes
            try {
                std::lock_guard<std::recursive_mutex> lock(boxesMutex);
                boxes.clear();
                LogInfo("已清理检测框列表");
            } catch (const std::exception& e) {
                LogError("清理检测框列表时异常: " + std::string(e.what()));
            } catch (...) {
                LogError("清理检测框列表时发生未知异常");
            }
            
            LogInfo("渲染器停止完成");
            
        } catch (const std::exception& e) {
            LogError("Stop方法异常: " + std::string(e.what()));
        } catch (...) {
            LogError("Stop方法发生未知异常");
        }
    }

    void Hide() {
        if (hwnd) {
            ShowWindow(hwnd, SW_HIDE);
        }
    }

    void SetBoxes(const std::vector<std::vector<int>>& boxCoords) {
        try {
            auto start_time = std::chrono::high_resolution_clock::now();
            LogInfo("开始设置检测框，数量: " + std::to_string(boxCoords.size()));
            
            // 极简优化：跳过重叠检测，直接处理所有框
            // 重叠检测的O(n²)复杂度是性能瓶颈
            std::vector<Box> newBoxes;
            newBoxes.reserve(boxCoords.size());
            
            auto parse_start = std::chrono::high_resolution_clock::now();
            for (const auto& coords : boxCoords) {
                if (coords.size() >= 4) {
                    Box box;
                    box.x1 = coords[0];
                    box.y1 = coords[1];
                    box.x2 = coords[2];
                    box.y2 = coords[3];
                    
                    auto color_start = std::chrono::high_resolution_clock::now();
                    // 快速颜色计算
                    box.color = CalculateAverageColor(box.x1, box.y1, box.x2, box.y2);
                    auto color_end = std::chrono::high_resolution_clock::now();
                    auto color_duration = std::chrono::duration_cast<std::chrono::microseconds>(color_end - color_start);
                    LogInfo("颜色计算耗时: " + std::to_string(color_duration.count()) + " 微秒");
                    
                    newBoxes.push_back(box);
                }
            }
            auto parse_end = std::chrono::high_resolution_clock::now();
            auto parse_duration = std::chrono::duration_cast<std::chrono::microseconds>(parse_end - parse_start);
            LogInfo("解析和颜色计算总耗时: " + std::to_string(parse_duration.count()) + " 微秒");
            
            auto lock_start = std::chrono::high_resolution_clock::now();
            // 只在更新boxes时持有锁
            {
                std::lock_guard<std::recursive_mutex> lock(boxesMutex);
                boxes = std::move(newBoxes);
                LogInfo("成功更新检测框列表，数量: " + std::to_string(boxes.size()));
            }
            auto lock_end = std::chrono::high_resolution_clock::now();
            auto lock_duration = std::chrono::duration_cast<std::chrono::microseconds>(lock_end - lock_start);
            LogInfo("锁操作耗时: " + std::to_string(lock_duration.count()) + " 微秒");
            
            auto update_start = std::chrono::high_resolution_clock::now();
            // 同步模式：立即更新显示
            UpdateLayeredWindowContent();
            auto update_end = std::chrono::high_resolution_clock::now();
            auto update_duration = std::chrono::duration_cast<std::chrono::microseconds>(update_end - update_start);
            LogInfo("窗口更新耗时: " + std::to_string(update_duration.count()) + " 微秒");
            
            auto total_end = std::chrono::high_resolution_clock::now();
            auto total_duration = std::chrono::duration_cast<std::chrono::microseconds>(total_end - start_time);
            LogInfo("SetBoxes总耗时: " + std::to_string(total_duration.count()) + " 微秒 (" + std::to_string(total_duration.count() / 1000.0) + " 毫秒)");
            
        } catch (const std::exception& e) {
            LogError("SetBoxes异常: " + std::string(e.what()));
        } catch (...) {
            LogError("SetBoxes发生未知异常");
        }
    }

    void ClearBoxes() {
        std::lock_guard<std::recursive_mutex> lock(boxesMutex);
        boxes.clear();
        // 同步模式：立即更新显示
        UpdateLayeredWindowContent();
    }

private:
    void Cleanup() {
        try {
            LogInfo("开始清理资源");
            
            // 清理GDI资源
            try {
                if (memBitmap && memDC) {
                    SelectObject(memDC, oldBitmap);
                    LogInfo("已恢复原始位图");
                }
                
                if (memBitmap) {
                    DeleteObject(memBitmap);
                    memBitmap = nullptr;
                    LogInfo("已删除内存位图");
                }
                
                if (memDC) {
                    DeleteDC(memDC);
                    memDC = nullptr;
                    LogInfo("已删除内存DC");
                }
            } catch (const std::exception& e) {
                LogError("清理GDI资源时异常: " + std::string(e.what()));
            } catch (...) {
                LogError("清理GDI资源时发生未知异常");
            }
            
            // 清理窗口句柄
            try {
                if (hwnd) {
                    DestroyWindow(hwnd);
                    hwnd = nullptr;
                    LogInfo("已销毁窗口");
                }
            } catch (const std::exception& e) {
                LogError("销毁窗口时异常: " + std::string(e.what()));
            } catch (...) {
                LogError("销毁窗口时发生未知异常");
            }
            
            // 最后清理boxes
            try {
                std::lock_guard<std::recursive_mutex> lock(boxesMutex);
                boxes.clear();
                LogInfo("已清理检测框列表");
            } catch (const std::exception& e) {
                LogError("最终清理检测框列表时异常: " + std::string(e.what()));
            } catch (...) {
                LogError("最终清理检测框列表时发生未知异常");
            }
            
            LogInfo("资源清理完成");
            
        } catch (const std::exception& e) {
            LogError("Cleanup方法异常: " + std::string(e.what()));
        } catch (...) {
            LogError("Cleanup方法发生未知异常");
        }
    }

    static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
        switch (uMsg) {
        case WM_NCHITTEST:
            return HTTRANSPARENT;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
};

class HttpServer {
private:
    SOCKET serverSocket;
    std::atomic<bool> running;
    std::unique_ptr<BoxRenderer> renderer;
    std::thread serverThread;

    std::string ParseJsonArray(const std::string& json) {
        size_t start = json.find('[');
        size_t end = json.rfind(']');
        if (start != std::string::npos && end != std::string::npos && end > start) {
            return json.substr(start, end - start + 1);
        }
        return "";
    }

    std::vector<std::vector<int>> ParseBoxes(const std::string& jsonArray) {
        std::vector<std::vector<int>> boxes;

        if (jsonArray.empty() || jsonArray == "[]") {
            return boxes;
        }

        std::string content = jsonArray;
        content = content.substr(1, content.length() - 2);

        std::stringstream ss(content);
        std::string item;

        while (std::getline(ss, item, ']')) {
            size_t bracketPos = item.find('[');
            if (bracketPos != std::string::npos) {
                std::string coords = item.substr(bracketPos + 1);

                std::vector<int> box;
                std::stringstream coordSs(coords);
                std::string coord;

                while (std::getline(coordSs, coord, ',')) {
                    coord.erase(0, coord.find_first_not_of(" \t"));
                    coord.erase(coord.find_last_not_of(" \t") + 1);

                    if (!coord.empty()) {
                        try {
                            box.push_back(std::stoi(coord));
                        }
                        catch (...) {
                            // ���Խ�������
                        }
                    }
                }

                if (box.size() >= 4) {
                    boxes.push_back(box);
                }
            }
        }

        return boxes;
    }

    void HandleRequest(SOCKET clientSocket) {
        try {
            auto request_start = std::chrono::high_resolution_clock::now();
            
            char buffer[4096] = { 0 };
            int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);

            if (bytesReceived > 0) {
                std::string request(buffer, bytesReceived);

                // 处理GET请求（健康检查）
                if (request.find("GET") == 0) {
                    std::string response =
                        "HTTP/1.1 200 OK\r\n"
                        "Content-Type: application/json\r\n"
                        "Access-Control-Allow-Origin: *\r\n"
                        "Content-Length: 15\r\n"
                        "\r\n"
                        "{\"status\":\"ok\"}";

                    send(clientSocket, response.c_str(), (int)response.length(), 0);
                }
                // 处理POST请求（设置检测框）
                else if (request.find("POST") == 0) {
                    auto parse_start = std::chrono::high_resolution_clock::now();
                    
                    size_t bodyStart = request.find("\r\n\r\n");
                    if (bodyStart != std::string::npos) {
                        std::string body = request.substr(bodyStart + 4);
                        std::string jsonArray = ParseJsonArray(body);
                        std::vector<std::vector<int>> boxes = ParseBoxes(jsonArray);

                        auto parse_end = std::chrono::high_resolution_clock::now();
                        auto parse_duration = std::chrono::duration_cast<std::chrono::microseconds>(parse_end - parse_start);
                        LogInfo("HTTP解析耗时: " + std::to_string(parse_duration.count()) + " 微秒");

                        auto render_start = std::chrono::high_resolution_clock::now();
                        if (boxes.empty()) {
                            renderer->ClearBoxes();
                        }
                        else {
                            renderer->SetBoxes(boxes);
                        }
                        auto render_end = std::chrono::high_resolution_clock::now();
                        auto render_duration = std::chrono::duration_cast<std::chrono::microseconds>(render_end - render_start);
                        LogInfo("渲染处理耗时: " + std::to_string(render_duration.count()) + " 微秒");
                    }

                    std::string response =
                        "HTTP/1.1 200 OK\r\n"
                        "Content-Type: application/json\r\n"
                        "Access-Control-Allow-Origin: *\r\n"
                        "Content-Length: 15\r\n"
                        "\r\n"
                        "{\"status\":\"ok\"}";

                    send(clientSocket, response.c_str(), (int)response.length(), 0);
                }
                else {
                    // 发送405 Method Not Allowed响应
                    std::string response =
                        "HTTP/1.1 405 Method Not Allowed\r\n"
                        "Content-Type: text/plain\r\n"
                        "Access-Control-Allow-Origin: *\r\n"
                        "Content-Length: 18\r\n"
                        "\r\n"
                        "Method Not Allowed";

                    send(clientSocket, response.c_str(), (int)response.length(), 0);
                }
            } else if (bytesReceived < 0) {
                LogError("接收数据失败，错误码: " + std::to_string(WSAGetLastError()));
            }
            
            auto request_end = std::chrono::high_resolution_clock::now();
            auto request_duration = std::chrono::duration_cast<std::chrono::microseconds>(request_end - request_start);
            LogInfo("HTTP请求总耗时: " + std::to_string(request_duration.count()) + " 微秒 (" + std::to_string(request_duration.count() / 1000.0) + " 毫秒)");
        }
        catch (const std::exception& e) {
            LogError("处理HTTP请求时发生异常: " + std::string(e.what()));
        }
        catch (...) {
            LogError("处理HTTP请求时发生未知异常");
        }

        closesocket(clientSocket);
    }

public:
    HttpServer() : serverSocket(INVALID_SOCKET), running(false) {
        renderer = std::make_unique<BoxRenderer>();
    }

    ~HttpServer() {
        Stop();
    }

    bool Start(int port = 3021) {
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
            LogError("WSAStartup失败，错误码: " + std::to_string(WSAGetLastError()));
            return false;
        }

        serverSocket = socket(AF_INET, SOCK_STREAM, 0);
        if (serverSocket == INVALID_SOCKET) {
            LogError("创建套接字失败，错误码: " + std::to_string(WSAGetLastError()));
            WSACleanup();
            return false;
        }

        sockaddr_in serverAddr = {};
        serverAddr.sin_family = AF_INET;

        // 使用 inet_pton 代替已弃用的 inet_addr
        if (inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr) != 1) {
            LogError("inet_pton失败");
            closesocket(serverSocket);
            WSACleanup();
            return false;
        }

        serverAddr.sin_port = htons((u_short)port);

        if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
            int error = WSAGetLastError();
            LogError("绑定端口失败，端口: " + std::to_string(port) + "，错误码: " + std::to_string(error));
            closesocket(serverSocket);
            WSACleanup();
            return false;
        }

        if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
            LogError("监听套接字失败，错误码: " + std::to_string(WSAGetLastError()));
            closesocket(serverSocket);
            WSACleanup();
            return false;
        }

        running.store(true);
        serverThread = std::thread(&HttpServer::ServerLoop, this);

        LogInfo("HTTP服务器启动成功，监听端口: " + std::to_string(port));
        return true;
    }

    bool InitializeRenderer() {
        try {
            if (!renderer->Create()) {
                LogError("创建BoxRenderer失败");
                return false;
            }

            renderer->Show();
            LogInfo("BoxRenderer初始化成功");
            return true;
        } catch (const std::exception& e) {
            LogError("初始化BoxRenderer时异常: " + std::string(e.what()));
            return false;
        } catch (...) {
            LogError("初始化BoxRenderer时发生未知异常");
            return false;
        }
    }

    void Stop() {
        running.store(false);

        if (serverSocket != INVALID_SOCKET) {
            closesocket(serverSocket);
            serverSocket = INVALID_SOCKET;
        }

        if (serverThread.joinable()) {
            serverThread.join();
        }

        if (renderer) {
            renderer->Stop();
        }

        WSACleanup();
    }

    void ServerLoop() {
        while (running.load()) {
            sockaddr_in clientAddr;
            int clientAddrSize = sizeof(clientAddr);

            SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrSize);
            if (clientSocket != INVALID_SOCKET) {
                std::thread clientThread(&HttpServer::HandleRequest, this, clientSocket);
                clientThread.detach();
            }
            else if (running.load()) {
                Sleep(10);
            }
        }
    }
};

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) {
    try {
        // 分配控制台窗口用于调试输出
        AllocConsole();
        freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
        freopen_s((FILE**)stderr, "CONOUT$", "w", stderr);
        freopen_s((FILE**)stdin, "CONIN$", "r", stdin);
        
        // 设置控制台编码为UTF-8以解决中文乱码问题
        SetConsoleOutputCP(CP_UTF8);
        SetConsoleCP(CP_UTF8);
        
        // 设置locale为UTF-8（使用更安全的方式）
        try {
            std::locale::global(std::locale(".UTF8"));
        } catch (...) {
            // 如果UTF8 locale不可用，使用默认locale
            std::locale::global(std::locale("C"));
        }
        
        LogInfo("程序启动");
        
        HttpServer server;

        if (!server.Start(3021)) {
            LogError("HTTP服务器启动失败");
            MessageBoxW(NULL, L"Failed to start HTTP server", L"Error", MB_OK | MB_ICONERROR);
            return 1;
        }
        
        LogInfo("HTTP服务器启动成功，监听端口3021");

        // 延迟初始化GUI组件，在消息循环启动后
        if (!server.InitializeRenderer()) {
            LogError("BoxRenderer初始化失败");
            MessageBoxW(NULL, L"Failed to initialize BoxRenderer", L"Error", MB_OK | MB_ICONERROR);
            return 1;
        }

        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        
        LogInfo("程序正常结束");
        return 0;
        
    } catch (const std::exception& e) {
        LogError("主函数异常: " + std::string(e.what()));
        MessageBoxA(NULL, ("Exception in main: " + std::string(e.what())).c_str(), "Error", MB_OK | MB_ICONERROR);
        return 1;
    } catch (...) {
        LogError("主函数发生未知异常");
        MessageBoxA(NULL, "Unknown exception in main", "Error", MB_OK | MB_ICONERROR);
        return 1;
    }
}